背景
今天接到一个任务,往一张 mysql 数据库表里导入一点文本数据,压缩文件在百度云上,一看 2 G 大小,百度云还各种限速,直接不想下载了,项目小姐姐问遇到啥问题?我更她说,下载困难,估计当时她哭笑不得,没办,最终还是得开工,直接拿 u盘 copy 的。
问题
废了几分钟才 copy 完,解压后 13.9G,挂不得她们都不知道里面装的是啥,然而难不倒我,linux 系统可谓是编程利器。
检查 csv 文件行数
1 | wc -l filename |
半天没跑出来,等不及,直接又上了另外一个命令
1 | head -n filename |
看了一下时间跨度,最终选定最后一天的数据进行导入,那就得锁定最后一天是从第几行开始的,一路tail -n filename 试出来了的,接下来就是把这部分数据截取到新文件
1 | tail -n filename > new_file.csv |
新文件只剩 1 个 G 了,突然想起还有字符编码的问题,我数据库用的是 utf-8,而 windows 平台的数据一般是 GBK 格式,一波百度后找到了 iconv 命令,一行命令就解决了,速度贼快,以后妈妈再也不用担心我的字符编码问题了
1 | iconv -f GBK -t UTF-8 input_file -o output_file |
然而开始要上传到服务器,阿里云的服务器上传数据也是需要一点时间。突然想,把文件切分一下吧,分批,或者开几个线程一起上传,又一波百度,发现了 split, 按行切分或者按大小切分
1 | split -l 1000000 filename |
然后愉快的先上传了一个小块到了服务器,打开 mysql,找到 load data 的命令,当然一开始不会那么成功,各种问题都会出现
-
双引号问题,默认会把双引号当做字段内容填充,就导致非 字符类型的数据不能导入
-
字符问题,utf-8 还要再重新指定,即使我的数据本来就是 utf-8
-
字段对应问题,插入的表很多字段都只能为空
-
更奇怪的是每次只成功了一半,还发现了 show warnings 可以查看警告信息,最后发现时 access 导出数据时是使用 \t 分割行的,orz
1
show warnings
最后附上成功导入的脚本
1 | LOAD DATA LOCAL INFILE "filename" INTO TABLE tablename |
测试成功后,将切割的数据合并
1 | cat x* > file |
再执行命令,大功告成!!
总结
敲命令还是很有成就感的,有时候要比使用某些软件效率要高,至少大多数软件对大文件读取都没有做优化,这对于经常接触大文件的人简直是噩梦!!atom 打开几M的数据都卡,替换更卡!果然使用 vim 替换功能,但是 vim 也不发操控大文件(几个G以上),当然我们可以写个脚本,可以将文件切割,逐一对文件进行操作!也不是不行!